<!DOCTYPE html>
<html>

<head>
  <title>Learn how to do Mutual TLS in Quarkus apps</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/blog/quarkus-mutual-tls/" />
  <meta property="og:title" content="Learn how to do Mutual TLS in Quarkus apps" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/blog/quarkus-mutual-tls/">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="post">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="active">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="post-page grid-wrapper">
  <div class="width-8-12 width-12-12-m doc-content">
    <div class="grid-wrapper">
      <div class="width-12-12">
        <p>
          <a href="/blog"><i class="fas fa-angle-left"></i> Back to all posts</a>
        </p>
      </div>
      <div class="width-12-12">
        <div class="post-date">
          April 27, 2020 
          
            <span class="tags"></span>
          
        </div>
        <h1 class="post-title">Learn how to do Mutual TLS in Quarkus apps</h1>
        <div class="grid-wrapper">
          <div class="width-8-12 width-12-12-m byline-wrapper">
            
            
              <img class="headshot" src="https://www.gravatar.com/avatar/70c46737c838f278b868139a5bce6c3c">
            
            <p class="byline">By Mattia Mascia</p>
          </div>
          <div class="width-12-12">
              <div class="paragraph">
<p>In this entry, we explore how to set mutual TLS encryption between two Quarkus applications manually.
Both on bare metal and Kubernetes.</p>
</div>
<div class="sect1">
<h2 id="what-is-mutual-tls-authentication"><a class="anchor" href="#what-is-mutual-tls-authentication"></a>What is Mutual TLS Authentication?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Mutual TLS authentication or two way authentication is an extension of Transport Layer Security (or “TLS”), and it ensures that traffic between the client and server is secure and trusted in both directions.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="why-mutual-tls"><a class="anchor" href="#why-mutual-tls"></a>Why Mutual TLS?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It is an additional security layer which verifies not only the server identity but also the client one.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="how-implement-it"><a class="anchor" href="#how-implement-it"></a>How implement it?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The best approach to implement Mutual TLS between two services is to delegate it to the infrastructure, for instance, a Service Mesh. This achieves a standard and secure way of communication and avoids that each application implements its solution. However, you are not always working on cutting edge environment.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s have a look at how to implement mTLS with Quarkus if you don&#8217;t have a service mesh environment like Istio.</p>
</div>
<div class="imageblock">
<div class="content">
<img src="/assets/images/posts/quarkus-mutual-tls/mutual_tls.png" alt="MutualTLS Diagram">
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="bootstrapping"><a class="anchor" href="#bootstrapping"></a>Bootstrapping</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s create both the server and client applications we will secure.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn io.quarkus:quarkus-maven-plugin:1.4.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=quarkus-server-mtls \
    -DclassName="org.acme.server.mtls.GreetingResource" \
    -Dextensions="rest-client, resteasy-jsonb, kubernetes-client" \
    -Dpath="/hello-server"</code></pre>
</div>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn io.quarkus:quarkus-maven-plugin:1.4.1.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=quarkus-client-mtls \
    -DclassName="org.acme.client.mtls.GreetingResource" \
    -Dextensions="rest-client, resteasy-jsonb, kubernetes-client" \
    -Dpath="/hello-client"</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="certificate-and-truststore-generation"><a class="anchor" href="#certificate-and-truststore-generation"></a>Certificate and Truststore generation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Of course, you need a server, client certificates and a truststore :)</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">keytool -genkeypair -storepass password -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore quarkus-server-mtls/src/main/resources/META-INF/resources/server.keystore

keytool -genkeypair -storepass password -keyalg RSA -keysize 2048 -dname "CN=client" -alias client -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore quarkus-client-mtls/src/main/resources/META-INF/resources/client.keystore</code></pre>
</div>
</div>
<div class="paragraph">
<p>For this example, we are simulating a truststore using:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>client.keystore</code> as truststore for the server application.</p>
</li>
<li>
<p><code>server.keystore</code> as truststore for the client application.</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">cp quarkus-server-mtls/src/main/resources/META-INF/resources/server.keystore quarkus-client-mtls/src/main/resources/META-INF/resources/client.truststore

cp quarkus-client-mtls/src/main/resources/META-INF/resources/client.keystore quarkus-server-mtls/src/main/resources/META-INF/resources/server.truststore</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hello-server-application"><a class="anchor" href="#hello-server-application"></a>Hello Server Application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Let&#8217;s open and configure the server <code>quarkus-server-mtls</code></p>
</div>
<div class="sect2">
<h3 id="enable-ssl-on-the-hello-server-application"><a class="anchor" href="#enable-ssl-on-the-hello-server-application"></a>Enable SSL on the Hello Server Application</h3>
<div class="paragraph">
<p>Add the following properties to enable SSL in your application <code>src/main/resources/application.properties</code></p>
</div>
<div class="listingblock">
<div class="title">application.properties</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.ssl.native=true

quarkus.http.ssl-port=8443
quarkus.http.ssl.certificate.key-store-file=META-INF/resources/server.keystore
quarkus.http.ssl.certificate.key-store-password=password

quarkus.http.port=0
quarkus.http.test-port=0</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
See the guide <a href="https://quarkus.io/guides/native-and-ssl">Using SSL with Native</a> to explore in details how SSL works in Quarkus.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="activate-client-authentication"><a class="anchor" href="#activate-client-authentication"></a>Activate client authentication</h3>
<div class="listingblock">
<div class="title">application.properties</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">quarkus.http.ssl.client-auth=required
quarkus.http.ssl.certificate.trust-store-file=META-INF/resources/server.truststore
quarkus.http.ssl.certificate.trust-store-password=password</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="update-greetingresource"><a class="anchor" href="#update-greetingresource"></a>Update GreetingResource</h3>
<div class="paragraph">
<p>To better see that the response is coming from the server application, let&#8217;s update the <code>org.acme.server.mtls.GreetingResource</code> class.</p>
</div>
<div class="listingblock">
<div class="title">org.acme.server.mtls.GreetingResource</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/hello-server")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello from server"; <i class="conum" data-value="1"></i><b>(1)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Change the return statement in <em>"hello from server"</em></td>
</tr>
</table>
</div>
<div class="paragraph">
<p>And the test class.</p>
</div>
<div class="listingblock">
<div class="title">org.acme.server.mtls.GreetingResourceTest</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@QuarkusTest
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello-server")
          .then()
             .statusCode(200)
             .body(is("hello from server")); <i class="conum" data-value="1"></i><b>(1)</b>
    }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Change the matcher in <em>"hello from server"</em></td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="run-it"><a class="anchor" href="#run-it"></a>Run it</h3>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>If everything is correct when you try to hit the <em>/hello-server</em> endpoint, you should expect the following error.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">curl -k https://localhost:8443/hello-server
curl: (35) error:1401E412:SSL routines:CONNECT_CR_FINISHED:sslv3 alert bad certificate</code></pre>
</div>
</div>
<div class="paragraph">
<p>This means that your client (curl) did not provide a trusted certificate when it connected to the server.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hello-client-application"><a class="anchor" href="#hello-client-application"></a>Hello Client Application</h2>
<div class="sectionbody">
<div class="paragraph">
<p>At this point, the server application is ready to accomplish Mutual TLS. Let&#8217;s open and configure the client <code>quarkus-client-mtls</code></p>
</div>
<div class="sect2">
<h3 id="add-rest-client-for-the-server-application"><a class="anchor" href="#add-rest-client-for-the-server-application"></a>Add Rest client for the server application</h3>
<div class="listingblock">
<div class="title">org.acme.client.mtls.GreetingService</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/")
@ApplicationScoped
@RegisterRestClient
public interface GreetingService {

    @GET
    @Path("/hello-server")
    @Produces(MediaType.TEXT_PLAIN)
    String hello();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Inject the GreetingService rest client on <code>org.acme.client.mtls.GreetingResource</code>.</p>
</div>
<div class="listingblock">
<div class="title">org.acme.client.mtls.GreetingResource</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@Path("/hello-client")
public class GreetingResource {

    @Inject <i class="conum" data-value="1"></i><b>(1)</b>
    @RestClient <i class="conum" data-value="2"></i><b>(2)</b>
    GreetingService greetingService;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return greetingService.hello(); <i class="conum" data-value="3"></i><b>(3)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>CDI <code>@Inject</code> annotation.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>MicroProfile <code>@RestClient</code> annotation.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Replace the return statement with the <code>greetingService.hello();</code>.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
See the guide <a href="https://quarkus.io/guides/rest-client">rest-client</a> to explore in details.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="update-the-unit-test"><a class="anchor" href="#update-the-unit-test"></a>Update the unit test</h3>
<div class="paragraph">
<p>Add <code>quarkus-junit5-mockito</code> dependency to your project.</p>
</div>
<div class="listingblock">
<div class="title">pom.xml</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">    &lt;dependency&gt;
      &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
      &lt;artifactId&gt;quarkus-junit5-mockito&lt;/artifactId&gt;
    &lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">org.acme.client.mtls.GreetingResourceTest</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@QuarkusTest
public class GreetingResourceTest {

    @InjectMock <i class="conum" data-value="1"></i><b>(1)</b>
    @RestClient <i class="conum" data-value="2"></i><b>(2)</b>
    GreetingService greetingService;

    @Test
    public void testHelloEndpoint() {
        Mockito.when(greetingService.hello()).thenReturn("hello from server"); <i class="conum" data-value="3"></i><b>(3)</b>

        given()
          .when().get("/hello-client")
          .then()
             .statusCode(200)
             .body(is("hello from server"));
    }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Inject the CDI bean.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>RestClient type.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Mock the hello request.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
See the guide <a href="https://quarkus.io/guides/getting-started-testing">Testing</a> to explore in details.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="configure-microprofile-rest-client-for-mutual-tls"><a class="anchor" href="#configure-microprofile-rest-client-for-mutual-tls"></a>Configure MicroProfile rest client for Mutual TLS</h3>
<div class="paragraph">
<p>Add the following properties to enable SSL in your application <code>src/main/resources/application.properties</code></p>
</div>
<div class="listingblock">
<div class="title">application.properties</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">org.acme.client.mtls.GreetingService/mp-rest/url=https://localhost:8443
org.acme.client.mtls.GreetingService/mp-rest/trustStore=classpath:/META-INF/resources/client.truststore
org.acme.client.mtls.GreetingService/mp-rest/trustStorePassword=password
org.acme.client.mtls.GreetingService/mp-rest/keyStore=classpath:/META-INF/resources/client.keystore
org.acme.client.mtls.GreetingService/mp-rest/keyStorePassword=password

quarkus.ssl.native=true</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="run-it-2"><a class="anchor" href="#run-it-2"></a>Run it</h3>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">mvn quarkus:dev</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now let&#8217;s hit the client <em>/hello-client</em> endpoint, and you should expect the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">curl http://localhost:8080/hello-client
hello from server</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="external-configuration"><a class="anchor" href="#external-configuration"></a>External Configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You do not want to have a certificate inside your application and Quarkus allows you to use external configuration and override the runtime application properties.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s check how we can do in Kubernetes / OpenShift.</p>
</div>
<div class="paragraph">
<p>During the application boostrapping you added the <code>kubernetes-config</code> extensions. The extension works by reading ConfigMaps directly from the Kubernetes API.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>In case you are in a restricted environment which not allow the role to view ConfigMap to your service account, you need to mount the external <code>config</code> directory under the current working directory, for instance <code>&lt;working-dir&gt;/config/application.properties</code></p>
</div>
<div class="paragraph">
<p>The <em>working directory</em> for:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>jvm <code>redhat-openjdk-18/openjdk18-openshift</code> image is <code>/deployments</code></p>
</li>
<li>
<p>native <code>ubi-quarkus-native-s2i:19.3.1-java11</code> image is <code>/home/quarkus</code></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">volumeMounts sample</div>
<div class="content">
<pre># ...

      volumes:
        - name: config
          configMap:
              name: client

# ...
          volumeMounts:
            - name: config
              mountPath: /deployments</pre>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="secret"><a class="anchor" href="#secret"></a>Secret</h3>
<div class="paragraph">
<p>Create server, client and truststore secret which contains your certificates and truststore. For instance:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">kubectl create secret generic server --from-file=tls/server/
kubectl create secret generic client --from-file=tls/client/
kubectl create secret generic truststore --from-file=tls/ca/truststore</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configmap"><a class="anchor" href="#configmap"></a>ConfigMap</h3>
<div class="paragraph">
<p>Create the server and client ConfigMap.</p>
</div>
<div class="listingblock">
<div class="title">server-ConfigMap.yaml</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">kind: ConfigMap
apiVersion: v1
metadata:
  name: server
data:
  application.properties: |
    quarkus.http.ssl.certificate.key-store-file=/deployments/tls/server.keystore
    quarkus.http.ssl.certificate.key-store-password=password
    quarkus.http.ssl.certificate.trust-store-file=/deployments/tls/ca/truststore
    quarkus.http.ssl.certificate.trust-store-password=password</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">client-ConfigMap.yaml</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">kind: ConfigMap
apiVersion: v1
metadata:
  name: client
data:
  application.properties: |
    org.acme.client.mtls.GreetingService/mp-rest/url=https://server:8443
    org.acme.client.mtls.GreetingService/mp-rest/trustStore=/deployments/tls/ca/truststore
    org.acme.client.mtls.GreetingService/mp-rest/trustStorePassword=password
    org.acme.client.mtls.GreetingService/mp-rest/keyStore=/deployments/tls/client.keystore
    org.acme.client.mtls.GreetingService/mp-rest/keyStorePassword=password</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="enable-kubernetes-config-extension-on-the-server-and-client-application"><a class="anchor" href="#enable-kubernetes-config-extension-on-the-server-and-client-application"></a>Enable <code>kubernetes-config</code> extension on the server and client application</h3>
<div class="paragraph">
<p>Add the following properties for the server application:</p>
</div>
<div class="listingblock">
<div class="title">application.properties</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs"># only when running in prod (Kubernetes environment)
%prod.quarkus.kubernetes-config.enabled=true

quarkus.kubernetes-config.config-maps=server</code></pre>
</div>
</div>
<div class="paragraph">
<p>and the client application:</p>
</div>
<div class="listingblock">
<div class="title">application.properties</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs"># only when running in prod (Kubernetes environment)
%prod.quarkus.kubernetes-config.enabled=true

quarkus.kubernetes-config.config-maps=client</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
See the guide <a href="https://quarkus.io/guides/kubernetes-config">Kubernetes Config</a> to explore in details.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="deploy-everything"><a class="anchor" href="#deploy-everything"></a>Deploy Everything</h3>
<div class="paragraph">
<p>Here an example for the client application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">kind: Deployment
apiVersion: apps/v1
metadata:
  name: client
  namespace: mtls
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client
  template:
    metadata:
      labels:
        app: client
    spec:
      volumes:
        - name: client
          secret:
            secretName: client
        - name: truststore
          secret:
            secretName: truststore
      containers:
        - name: client
          image: 'image-registry.openshift-image-registry.svc:5000/mtls/client:latest'
          ports:
            - containerPort: 8443
              protocol: TCP
          resources: {}
          volumeMounts:
            - name: client
              readOnly: true
              mountPath: /deployments/tls
            - name: truststore
              readOnly: true
              mountPath: /deployments/tls/ca</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
See this instruction <a href="https://github.com/openlab-red/quarkus-mtls-quickstart/tree/master/deploy" class="bare">https://github.com/openlab-red/quarkus-mtls-quickstart/tree/master/deploy</a> to explore in details.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="conclusion"><a class="anchor" href="#conclusion"></a>Conclusion</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You have successfully implemented a Mutual TLS with Quarkus.
The full Quarkus Mutual TLS example is available in the github repository mentioned in the links section.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="links"><a class="anchor" href="#links"></a>Links</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>GitHub repository: <a href="https://github.com/openlab-red/quarkus-mtls-quickstart" class="bare">https://github.com/openlab-red/quarkus-mtls-quickstart</a></p>
</li>
</ul>
</div>
</div>
</div>
              
          </div>
          <div class="width-12-12"><div class="share-page">
  <a class="share-linkedin" href="https://www.linkedin.com/shareArticle?mini=true&url=https://quarkus.io/blog/quarkus-mutual-tls/&title=Learn how to do Mutual TLS in Quarkus apps" rel="nofollow" target="_blank" title="Share on LinkedIn">
    <img src="/assets/images/share-page/icons_social-linkedin.png"/>
  </a>
  <a class="share-twitter" href="https://twitter.com/intent/tweet?text=Learn how to do Mutual TLS in Quarkus apps&url=https://quarkus.io/blog/quarkus-mutual-tls/&via=quarkusio&related=quarkusio" rel="nofollow" target="_blank" title="Share on Twitter">
    <img src="/assets/images/share-page/icons_social-twitter.png"/>
  </a>
  <a class="share-facebook" href="https://facebook.com/sharer.php?u=https://quarkus.io/blog/quarkus-mutual-tls/" rel="nofollow" target="_blank" title="Share on Facebook">
    <img src="/assets/images/share-page/icons_social-facebook.png"/>
  </a>
  <a class="share-reddit" href="http://www.reddit.com/submit?url=https://quarkus.io/blog/quarkus-mutual-tls/" onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=900,height=500,toolbar=1,resizable=0'); return false;" title="Share on Reddit" >
    <img src="/assets/images/share-page/icons_social-reddit.png"/>
  </a>
  <a class="share-email" href="mailto:?subject=Learn how to do Mutual TLS in Quarkus apps&amp;body=Learn how to do Mutual TLS in Quarkus apps https://quarkus.io/blog/quarkus-mutual-tls/" title="Share via Email" >
    <img src="/assets/images/share-page/icons_social-email.png"/>
  </a>
</div>
</div>
        </div>
      </div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
